/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.lcm.metadata.inner.api.utils;

import com.inspur.edp.lcm.metadata.inner.api.IdeLogService;
import com.inspur.edp.lcm.metadata.inner.api.data.PublishStatus;
import com.inspur.edp.lcm.metadata.inner.api.enm.StageEnum;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.util.Objects;

public class IdeLogUtils {

    /**
     * 阶段执行成功标识
     */
    public static final String SUCCESS = "success";
    /**
     * 阶段执行失败标识
     */
    public static final String Fail = "fail";
    private static int count = 0;
    private static IdeLogService ideLogService;
    private static final Object lockObject = new Object();
    /**
     * 请求唯一ID
     */
    private static final ThreadLocal<String> requestIdThreadLocal = ThreadLocal.withInitial(() -> null);
    /**
     * 阶段状态
     */
    private static final ThreadLocal<String> stageStatusThreadLocal = ThreadLocal.withInitial(() -> SUCCESS);
    /**
     * 是否重启标识
     */
    private static final ThreadLocal<Boolean> restartThreadLocal = ThreadLocal.withInitial(() -> false);
    /**
     * 执行阶段的最小进度值
     */
    private static final ThreadLocal<Integer> minProcessThreadLocal = ThreadLocal.withInitial(() -> 0);
    /**
     * 执行阶段的最大进度值
     */
    private static final ThreadLocal<Integer> maxProcessThreadLocal = ThreadLocal.withInitial(() -> 0);
    /**
     * 生成型标识
     */
    private static final ThreadLocal<Boolean> isGenerationThreadLocal = ThreadLocal.withInitial(() -> true);

    public static IdeLogService getIdeLogService() {
        try {
            if (ideLogService == null && count == 0) {
                synchronized (lockObject) {
                    ideLogService = SpringBeanUtils.getBean(IdeLogService.class);
                    count++;
                }
            }
            return ideLogService;
        } catch (Exception e) {
            return null;
        }
    }

    public static void syncProcess(PublishStatus publishStatus) {
        IdeLogService ideLogService = getIdeLogService();
        if (Objects.nonNull(ideLogService)) {
            ideLogService.syncProcess(requestIdThreadLocal.get(), publishStatus);
        }
    }

    public static void syncProcess(String id, PublishStatus publishStatus) {
        IdeLogService ideLogService = getIdeLogService();
        if (Objects.nonNull(ideLogService)) {
            ideLogService.syncProcess(id, publishStatus);
        }
    }

    public static void setRequestId(String id) {
        requestIdThreadLocal.set(id);
    }

    public static String getRequestId() {
        return requestIdThreadLocal.get();
    }

    public static void setMinProcess(int process) {
        minProcessThreadLocal.set(process);
    }

    public static int getMinProcess() {
        return minProcessThreadLocal.get();
    }

    public static void removeMinProcess() {
        minProcessThreadLocal.remove();
    }

    public static void setMaxProcess(int process) {
        maxProcessThreadLocal.set(process);
    }

    public static int getMaxProcess() {
        return maxProcessThreadLocal.get();
    }

    public static void removeMaxProcess() {
        maxProcessThreadLocal.remove();
    }

    public static void setGenerationThreadLocal(boolean isGeneration) {
        isGenerationThreadLocal.set(isGeneration);
    }

    public static boolean getGenerationThreadLocal() {
        return isGenerationThreadLocal.get();
    }

    public static void removeGenerationThreadLocal() {
        isGenerationThreadLocal.remove();
    }

    public static void removeRequestId() {
        requestIdThreadLocal.remove();
    }

    public static void setStageStatus(String stageStatus) {
        stageStatusThreadLocal.set(stageStatus);
    }

    public static String getStageStatus() {
        return stageStatusThreadLocal.get();
    }

    public static void setRestart(boolean restart) {
        restartThreadLocal.set(restart);
    }

    public static boolean isRestart() {
        return restartThreadLocal.get();
    }

    public static void removeRestart() {
        restartThreadLocal.remove();
    }

    public static void removeStageStatus() {
        stageStatusThreadLocal.remove();
    }

    /**
     * 进度分配规则: (1) 按工程等比例划分100; (2) 0生成代码、1maven编译、2扩展编译、3提取、4部署划分比例为 2 : 6 : 10 : 1 :1
     *
     * @param projectSize 工程数量
     * @param stageEnum   阶段
     * @return
     */
    public static int calcProcess(int projectSize, int currentSize, StageEnum stageEnum) {
        if (currentSize > projectSize) {
            return 0;
        }
        switch (stageEnum) {
            case GENERATE:
                return StageEnum.GENERATE.getProcessValue() * currentSize / projectSize;
            case MAVEN_COMPILE:
                return StageEnum.GENERATE.getProcessValue() + StageEnum.MAVEN_COMPILE.getProcessValue() * currentSize / projectSize;
            case EXTEND_COMPILE:
                return StageEnum.GENERATE.getProcessValue() + StageEnum.MAVEN_COMPILE.getProcessValue() + StageEnum.EXTEND_COMPILE.getProcessValue() * currentSize / projectSize;
            case EXTRACT:
                return StageEnum.GENERATE.getProcessValue() + StageEnum.MAVEN_COMPILE.getProcessValue() + StageEnum.EXTEND_COMPILE.getProcessValue() + StageEnum.EXTRACT.getProcessValue() * currentSize / projectSize;
            case DEPLOY:
                return StageEnum.GENERATE.getProcessValue() + StageEnum.MAVEN_COMPILE.getProcessValue() + StageEnum.EXTEND_COMPILE.getProcessValue() + StageEnum.EXTRACT.getProcessValue() + StageEnum.DEPLOY.getProcessValue() * currentSize / projectSize;
            default:
                return 99;
        }
    }
}
